<?php

namespace Api\Openapi;

use Core\Env;
use S\Config;
use S\Http;

/**
 * Class Msg
 * @package Api\Openapi
 * @description 消息服务类
 *
 * 以下为使用样例：
 *
 * i. 发送sms消息
 *
 * $sdk = new \Api\Openapi\Msg();
 * $result = $sdk->sendSms("18513497342", "Bonjour!");
 *
 * ii. 发送email
 *
 * 模版需要联系以下人员协同配置：
 * dongzhe.xin@beebank.com
 * yu.zhao@beebank.com
 *
 * $sdk = new \Api\Openapi\Msg();
 * $result = $sdk->sendMail(
 *     "dongzhe.xin@beebank.com",
 *     1,  //由后台分配，敬请联系以上协助人员
 *     array("辛东哲", "你好！"),  //模版填充处内容，根据实际模版进行填写
 *     array(
 *         array(
 *             "name" => "电子合同.pdf",  //附件名称
 *             "path" => "/tmp/attachment/电子合同.pdf",  //附件文件本地绝对路径
 *         ),
 *     ),
 * );
 */
class Msg extends Util {

    const URI_MSG_PUB = "/msg/pub";  //异步回调
    const URI_MSG_SMS = "/msg/sms";  //发送sms简讯
    const URI_MSG_MAIL = "/msg/mail";  //发送电子邮件

    const HTTP_METHOD_POST = "POST";  //Http post方法
    const HTTP_METHOD_GET = "GET";  //Http get方法

    /**
     * 异步回调-单笔
     *
     * @param string $url
     * @param string $method
     * @param array $data default array()
     *
     * @return bool
     */
    public function pubSingle($url, $method, array $data = array()) {
        $body = array(
            array(
                "urls" => array($url),
                "method" => $method,
                "data" => $data,
            ),
        );
        $params = array(
            "header" => array(),
            "body" => $body,
        );

        try{
            return self::request(self::URI_MSG_PUB, $params)["body"]["result"];
        } catch (\Exception $e) {
            self::$_err_code = $e->getCode();
            self::$_err_msg = $e->getMessage();

            return false;
        }
    }

    /**
     * 发送简讯
     *
     * @param string $mobile 手机号码
     * @param string $msg 简讯内容
     * @param int $timeout 超时时间
     * @param int $mode 短信签名, 由运营商前缀或后缀
     * @param int $is_retry default 0 重试标志 0-不重试 1-重试 验证码类短信不能使用重试, 防止号码进入运营商黑名单
     *
     * @return bool true-发送成功 false-发送失败，此时调用getErrMsg获取详细错误资讯
     */
    public function sendSms($mobile, $msg, $timeout = 2, $mode = null, $is_retry = 0){
        $body = array(
            "mobile" => $mobile,
            "msg" => $msg,
            "retry" => $is_retry,
        );
        if($mode){
            $body['mode'] = $mode;
        }
        $params = array(
            "header" => array(),
            "body" => $body,
        );

        try{
            return self::request(self::URI_MSG_SMS, $params, $timeout)["body"]["result"];
        } catch (\Exception $e) {
            self::$_err_code = $e->getCode();
            self::$_err_msg = $e->getMessage();

            return false;
        }
    }

    /**
     * 发送电子邮件
     *
     * @param string $email 接收方邮件地址
     * @param int $template_id 模版id
     * @param array $data 发送内容，按照模版中填充数据顺序传入
     * @param array $attr_list 附件列表，包括：name－附件名称 path－本地附件绝对路径
     * @param string $from_nickname default null 发送方昵称
     * @param string $nickname default null 接收方昵称
     * @param string $email_tag default null 邮件标签
     * @param int $priority default null 优先级
     * @param int $group_id default null 模版组id
     * @param bool $test_flag default false 测试邮件标志
     * @param int $timeout default 30000
     *
     * @return bool true-发送成功 false-发送失败，此时调用getErrMsg获取详细错误资讯
     */
    public function sendMail($email, $template_id, array $data = array(), $attr_list = array(), $from_nickname = null, $nickname = null, $email_tag = null,
                             $priority = null, $group_id = null, $test_flag = false, $timeout = 30000){
        $params = array(
            "email" => $email,
            "template_id" => $template_id,
            "msg" => json_encode($data),
            "sender_nickname" => $from_nickname,
            "receiver_nickname" => $nickname,
            "tag" => $email_tag,
            "priority" => intval($priority),
            "group_id" => intval($group_id),
            "test_flag" => $test_flag,
        );

        $timestamp = time();
        $m = self::getSign($timestamp, $params);
        $get_params = array(
            "appkey" => Config::confSecurity("openapi.app_key"),
            "t" => $timestamp,
            "m" => $m,
        );
        $get_strs = array();
        foreach ($get_params as $key => $val) {
            $get_strs[] = "{$key}={$val}";
        }

        $options = array(
            'multipart' => array(),
        );
        foreach ($params as $key => $val) {
            $options['multipart'][] = array(
                'name'     => $key,
                'contents' => (string)$val,
            );
        }
        foreach ($attr_list as $key => $attr) {
            $options['multipart'][] = array(
                'name'     => urlencode("attachment_list[{$key}]"),
                'contents' => fopen(realpath($attr["path"]), 'r'),
                'filename' => $attr["name"],
            );
        }

        $curl = new \S\Http((Env::isProductEnv() ? self::PRD_URL : self::TEST_URL));
        $response = $curl->request(\S\Http::METHOD_POST, self::URI_MSG_MAIL . "?" . implode("&", $get_strs), '', $options);

        if (!$response) {
            self::$_err_msg = "empty response from openapi";

            return false;
        }
        $result = json_decode($response, true);
        if (!$result) {
            self::$_err_msg = "error format response from openapi";

            return false;
        }
        if (self::ERR_CODE_SUCCESS != $result["retcode"]) {
            self::$_err_code = $result["retcode"];
            self::$_err_msg = $result["msg"];

            return false;
        }

        unset($result["retcode"]);
        unset($result["msg"]);

        return $result["body"]["result"];
    }

} 